/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package seGobangClient.gaming;
import java.util.List;
import javax.vecmath.Point2i;
import java.util.ArrayList;
import java.util.HashMap;

/*
 * 该类的Isforbid是核心方法，用于判断落子是否形成禁手，每次使用前须用当前棋局和最后的落子位置
 * 将对象初始化
 */

public class ForbiddenTool {
   private HashMap<Point2i,Byte> table;
   private int l=15;
   private Point2i last;
   private Point2i left,right,up,down,leftup,rightdown,rightup,leftdown;
   private int ver=0;
   private int hor=0;
   private int rs=0;
   private int ls=0;
        ArrayList<Point2i> vl=new ArrayList<Point2i>();
        ArrayList<Point2i> hl=new ArrayList<Point2i>();
        ArrayList<Point2i> rl=new ArrayList<Point2i>();
        ArrayList<Point2i> ll=new ArrayList<Point2i>();
  public ForbiddenTool(HashMap<Point2i,Byte> chesses,Point2i lastchess)
   {
       table=chesses;
       HashMap<Point2i,Byte> tempTable=new HashMap<Point2i,Byte>();
       for(int i=0; i<15;i++)
           for(int j=0; j<15; j++){
               tempTable.put(new Point2i(i,j), table.get(new Point2i(i-7,j-7)));
           }
       table=tempTable;
       last=new Point2i(lastchess.x+7,lastchess.y+7);
   }   
   public ArrayList<Point2i> get_forbidden_chesses()
   {
         ArrayList<Point2i> forbid=new ArrayList<Point2i>();
         forbid.addAll(vl);
         forbid.addAll(hl);
         forbid.addAll(rl);
         forbid.addAll(ll);
         return forbid;
   }
  
  public void show_chesstable()
  {
      System.out.print("  ");for(int i=0;i<10;i++) System.out.print(" "+i);
      System.out.println();
      for(int i=0;i<l;i++)
      {  
          if(i<=9)System.out.print(i+"  ");
          else System.out.print(i+" ");
          for(int j=0;j<l;j++)
         {
            if(table.get(new Point2i(i,j)).intValue()==-1)
              System.out.print("b ");
            else if(table.get(new Point2i(i,j)).intValue()==1)
              System.out.print("w ");
            else  System.out.print("k ");
         }
          System.out.println();
      }
      // System.out.println(iChesses);
  }
  
 
  private void side()
  {
     /**
      确定水平非黑棋夹击位置
      */
      int curi=last.x;
      int curj=last.y;
     
      while(--curj>=0)
      {
         if(table.get(new Point2i(curi,curj)).intValue()!=-1)
         {
             left=new Point2i(curi,curj); break;
         }
      }
      left=new Point2i(curi,curj);
     
      curi=last.x;
      curj=last.y;
     while(++curj<l)
      {
         if(table.get(new Point2i(curi,curj)).intValue()!=-1)
         {right=new Point2i(curi,curj); break;}
         
      }
     right=new Point2i(curi,curj);
     
     /**
      确定竖直非黑棋夹击位置
      */
      curi=last.x;
      curj=last.y;
      while((--curi)>=0)
      {
         if(table.get(new Point2i(curi,curj)).intValue()!=-1)
         {up=new Point2i(curi,curj); break;} 
      }
    up=new Point2i(curi,curj);
     
      curi=last.x;
      curj=last.y;
   
     while((++curi)<l)
      {
         if(table.get(new Point2i(curi,curj)).intValue()!=-1)
         {down=new Point2i(curi,curj); break;}
        
      }
       down=new Point2i(curi,curj);
       /**
      确定逆斜对角非黑棋夹击位置
      */
      curi=last.x;
     curj=last.y;
  
      while((--curj)>=0&&(--curi)>=0)
      {
         if(table.get(new Point2i(curi,curj)).intValue()!=-1)
         {leftup=new Point2i(curi,curj); break;}
      }
       if(curj<0) leftup=new Point2i(curi-1,curj);
       else  leftup=new Point2i(curi,curj);
    
      curi=last.x;
      curj=last.y;
     while((++curj)<l&&(++curi)<l)
      {
         if(table.get(new Point2i(curi,curj)).intValue()!=-1)
         {rightdown=new Point2i(curi,curj); break;}
      }
       if(curj>l) rightdown=new Point2i(curi+1,curj);
       else  rightdown=new Point2i(curi,curj);
      
       /**
      确定正斜对角非黑棋夹击位置
      */
      curi=last.x;
     curj=last.y;
    
      while((++curj)<l&&(--curi)>=0)
      {
         if(table.get(new Point2i(curi,curj)).intValue()!=-1)
         {rightup=new Point2i(curi,curj); break;}
      }
       if(curj>=l) rightup=new Point2i(curi-1,curj);
       else  rightup=new Point2i(curi,curj);
    
      curi=last.x;
      curj=last.y;
   
     while((--curj)>=0&&(++curi)<l)
      {
         if(table.get(new Point2i(curi,curj)).intValue()!=-1)
         {leftdown=new Point2i(curi,curj); break;}
      }
       if(curj<0) leftdown=new Point2i(curi+1,curj);
       else  leftdown=new Point2i(curi,curj);
  }
  
  private void dealver()
  {
         vl.clear();
         ver=0;
      int off=right.y-left.y;
      if(off>=7) //长连
      {
           for(int i=left.y+1;i<right.y;i++)
             vl.add(new Point2i(left.x,i));
           ver=off-1;
      }
      else if(off==6)//5连获胜
      {
       for(int i=left.y+1;i<right.y;i++)
            vl.add(new Point2i(left.x,i));
          ver=5;
      }
      else if(off==5)//?0x00?
      {
           if(Isalive(left)&&Isalive(right))
           {
               for(int i=left.y+1;i<right.y;i++)
                 vl.add(new Point2i(left.x,i));
               ver=4;
           }
      }
      else if(off==4)
      {
         
          // _00x_
          if(Isalive(left)&&Isalive(right)){
              if(left.y-1>=0&&table.get(new Point2i(left.x,left.y-1)).intValue()==-1&&Isalive(new Point2i(left.x,left.y-2)))
                {
                     vl.add(new Point2i(left.x,left.y-1));
                    for(int i=left.y+1;i<right.y;i++)
                       vl.add(new Point2i(left.x,i));
                      ver=4;
                }
              else if(right.y+1<l&&table.get(new Point2i(right.x,right.y+1)).intValue()==-1&&Isalive(new Point2i(left.x,right.y+2)))
                {
                     for(int i=left.y+1;i<right.y;i++)
                       vl.add(new Point2i(left.x,i));
                     vl.add(new Point2i(right.x,right.y+1));
                      ver=4;
                }  
              else {
                    for(int i=left.y+1;i<right.y;i++)
                       vl.add(new Point2i(left.x,i));
                    ver=3;
              }
           } 
      }
      else if(off==3){
          // _0x_
          if(Isalive(left)&&Isalive(right)){
            //_0x_0_   
            if(right.y+2<l&&table.get(new Point2i(right.x,right.y+1)).intValue()==-1&&table.get(new Point2i(right.x,right.y+2)).intValue()==0)
            {
                 for(int i=left.y+1;i<right.y;i++)
                       vl.add(new Point2i(left.x,i));
                 vl.add(new Point2i(right.x,right.y+1));
                 ver=3;
            }
            //_0x_00  
            else if(right.y+2<l&&table.get(new Point2i(right.x,right.y+1)).intValue()==-1&&table.get(new Point2i(right.x,right.y+2)).intValue()==-1&&Isalive(new Point2i(right.x,right.y+3)))
            {
                 for(int i=left.y+1;i<right.y;i++)
                       vl.add(new Point2i(left.x,i));
                 vl.add(new Point2i(right.x,right.y+1));
                 vl.add(new Point2i(right.x,right.y+2));
                 ver=4;
            }
            //  _0_0x_ 
            else if(left.y-2>=0&&table.get(new Point2i(left.x,left.y-1)).intValue()==-1&&table.get(new Point2i(left.x,left.y-2)).intValue()==0)
            {
                vl.add(new Point2i(left.x,left.y-1)); 
                for(int i=left.y+1;i<right.y;i++)
                       vl.add(new Point2i(left.x,i));
                 ver=3;
            }
             //  00_0x_ 
            else if(left.y-2>=0&&table.get(new Point2i(left.x,left.y-1)).intValue()==-1&&table.get(new Point2i(left.x,left.y-2)).intValue()==-1&&Isalive(new Point2i(left.x,left.y-3)))
            {
                vl.add(new Point2i(left.x,left.y-2)); 
                vl.add(new Point2i(left.x,left.y-1)); 
                for(int i=left.y+1;i<right.y;i++)
                       vl.add(new Point2i(left.x,i));
                 ver=4;
            }
          }
      }
      else if(off==2){
         // _x_
          if(Isalive(left)&&Isalive(right)){
            //_x_00_   
            if(right.y+3<l&&table.get(new Point2i(right.x,right.y+1)).intValue()==-1&&table.get(new Point2i(right.x,right.y+2)).intValue()==-1&&table.get(new Point2i(right.x,right.y+3)).intValue()==0)
            {
                 for(int i=left.y+1;i<right.y;i++)
                       vl.add(new Point2i(left.x,i));
                 vl.add(new Point2i(right.x,right.y+1));
                  vl.add(new Point2i(right.x,right.y+2));
                 ver=3;
            }
            //_x_000  
            else if(right.y+3<l&&table.get(new Point2i(right.x,right.y+1)).intValue()==-1&&table.get(new Point2i(right.x,right.y+2)).intValue()==-1&&table.get(new Point2i(right.x,right.y+3)).intValue()==-1&&Isalive(new Point2i(right.x,right.y+4)))
            {
                 for(int i=left.y+1;i<right.y;i++)
                       vl.add(new Point2i(left.x,i));
                 vl.add(new Point2i(right.x,right.y+1));
                 vl.add(new Point2i(right.x,right.y+2));
                 vl.add(new Point2i(right.x,right.y+3));
                 ver=4;
            }
            //  _00_x_ 
            else if(left.y-3>=0&&table.get(new Point2i(left.x,left.y-1)).intValue()==-1&&table.get(new Point2i(left.x,left.y-2)).intValue()==-1&&table.get(new Point2i(left.x,left.y-3)).intValue()==0)
            {
                vl.add(new Point2i(left.x,left.y-2)); 
                vl.add(new Point2i(left.x,left.y-1)); 
                for(int i=left.y+1;i<right.y;i++)
                       vl.add(new Point2i(left.x,i));
                 ver=3;
            }
             //  000_x_ 
            else if(left.y-3>=0&&table.get(new Point2i(left.x,left.y-1)).intValue()==-1&&table.get(new Point2i(left.x,left.y-2)).intValue()==-1&&table.get(new Point2i(left.x,left.y-3)).intValue()==-1&&Isalive(new Point2i(left.x,left.y-4)))
            {
                vl.add(new Point2i(left.x,left.y-3)); 
                vl.add(new Point2i(left.x,left.y-2)); 
                vl.add(new Point2i(left.x,left.y-1)); 
                for(int i=left.y+1;i<right.y;i++)
                       vl.add(new Point2i(left.x,i));
                 ver=4;
            }
          } 
      } 
  }
  private void dealhor()
  {
      hl.clear();
         hor=0;
      int off=down.x-up.x;
      if(off>=7) //长连
      {
           for(int i=up.x+1;i<down.x;i++)
             hl.add(new Point2i(i,up.y));
           hor=off-1;
      }
      else if(off==6)//5连获胜
      {
       for(int i=up.x+1;i<down.x;i++)
             hl.add(new Point2i(i,up.y));
          hor=5;
      }
      else if(off==5)//?0x00?
      {
           if(Isalive(up)&&Isalive(down))
           {
               for(int i=up.x+1;i<down.x;i++)
                 hl.add(new Point2i(i,up.y));
               hor=4;
           }
      }
      else if(off==4)
      {
         
          // _00x_
          if(Isalive(up)&&Isalive(down)){
              if(up.x-1>=0&&table.get(new Point2i(up.x-1,up.y)).intValue()==-1&&Isalive(new Point2i(up.x-2,up.y)))
                {
                     hl.add(new Point2i(up.x-1,up.y));
                   for(int i=up.x+1;i<down.x;i++)
                      hl.add(new Point2i(i,up.y));
                      hor=4;
                }
              else if(down.x+1<l&&table.get(new Point2i(down.x+1,down.y)).intValue()==-1&&Isalive(new Point2i(down.x+2,down.y)))
                {
                    for(int i=up.x+1;i<down.x;i++)
                      hl.add(new Point2i(i,up.y));
                     hl.add(new Point2i(down.x+1,down.y));
                      hor=4;
                }  
              else {
                    for(int i=up.x+1;i<down.x;i++)
                      hl.add(new Point2i(i,up.y));
                    hor=3;
              }
           } 
      }
      else if(off==3){
          
          // _0x_
          if(Isalive(up)&&Isalive(down)){
            //_0x_0_   
            if(down.x+2<l&&table.get(new Point2i(down.x+1,down.y)).intValue()==-1&&table.get(new Point2i(down.x+2,down.y)).intValue()==0)
            {
                for(int i=up.x+1;i<down.x;i++)
                      hl.add(new Point2i(i,up.y));
                 hl.add(new Point2i(down.x+1,down.y));
                 hor=3;
            }
            //_0x_00  
            else if(down.x+2<l&&table.get(new Point2i(down.x+1,down.y)).intValue()==-1&&table.get(new Point2i(down.x+2,down.y)).intValue()==-1&&Isalive(new Point2i(down.x+3,down.y)))
            {
                for(int i=up.x+1;i<down.x;i++)
                      hl.add(new Point2i(i,up.y));
                  hl.add(new Point2i(down.x+1,down.y));
                  hl.add(new Point2i(down.x+2,down.y));
                 hor=4;
            }
            //  _0_0x_ 
            else if(up.x-2>=0&&table.get(new Point2i(up.x-1,up.y)).intValue()==-1&&table.get(new Point2i(up.x-2,up.y)).intValue()==0)
            {
                hl.add(new Point2i(up.x-1,up.y)); 
               for(int i=up.x+1;i<down.x;i++)
                      hl.add(new Point2i(i,up.y));
                 hor=3;
            }
             //  00_0x_ 
            else if(up.x-2>=0&&table.get(new Point2i(up.x-1,up.y)).intValue()==-1&&table.get(new Point2i(up.x-2,up.y)).intValue()==-1&&Isalive(new Point2i(up.x-3,up.y)))
            {
                hl.add(new Point2i(up.x-2,up.y)); 
                hl.add(new Point2i(up.x-1,up.y)); 
                for(int i=up.x+1;i<down.x;i++)
                      hl.add(new Point2i(i,up.y));
                 hor=4;
            }
          }
      }
      else if(off==2){
       
          // _x_
          if(Isalive(up)&&Isalive(down)){
            //_x_00_   
            if(down.x+3<l&&table.get(new Point2i(down.x+1,down.y)).intValue()==-1&&table.get(new Point2i(down.x+2,down.y)).intValue()==-1&&table.get(new Point2i(down.x+3,down.y)).intValue()==0)
            {
                for(int i=up.x+1;i<down.x;i++)
                      hl.add(new Point2i(i,up.y));
                 hl.add(new Point2i(down.x+1,down.y));
                  hl.add(new Point2i(down.x+2,down.y));
                 hor=3;
            }
            //_x_000  
            else if(down.x+3<l&&table.get(new Point2i(down.x+1,down.y)).intValue()==-1&&table.get(new Point2i(down.x+2,down.y)).intValue()==-1&&table.get(new Point2i(down.x+3,down.y)).intValue()==-1&&Isalive(new Point2i(down.x+4,down.y)))
            {
                 for(int i=up.x+1;i<down.x;i++)
                      hl.add(new Point2i(i,up.y));
                hl.add(new Point2i(down.x+1,down.y));
                  hl.add(new Point2i(down.x+2,down.y));
                   hl.add(new Point2i(down.x+3,down.y));
                 hor=4;
            }
            //  _00_x_ 
            else if(up.x-3>=0&&table.get(new Point2i(up.x-1,up.y)).intValue()==-1&&table.get(new Point2i(up.x-2,up.y)).intValue()==-1&&table.get(new Point2i(up.x-3,up.y)).intValue()==0)
            {
                hl.add(new Point2i(up.x-2,up.y)); 
                hl.add(new Point2i(up.x-1,up.y)); 
               for(int i=up.x+1;i<down.x;i++)
                      hl.add(new Point2i(i,up.y));
                 hor=3;
            }
             //  000_x_ 
            else if(up.x-3>=0&&table.get(new Point2i(up.x-1,up.y)).intValue()==-1&&table.get(new Point2i(up.x-2,up.y)).intValue()==-1&&table.get(new Point2i(up.x-3,up.y)).intValue()==-1&&Isalive(new Point2i(up.x-4,up.y)))
            {
                 hl.add(new Point2i(up.x-3,up.y)); 
                hl.add(new Point2i(up.x-2,up.y)); 
                hl.add(new Point2i(up.x-1,up.y)); 
                for(int i=up.x+1;i<down.x;i++)
                      hl.add(new Point2i(i,up.y));
                 hor=4;
            }
          } 
      } 
  }
  private void dealrs()
  {
     rl.clear();
         rs=0;
      int off=rightup.y-leftdown.y;
      if(off>=7) //长连
      {
          int count=1; 
          for(int i=leftdown.y+1;i<rightup.y;i++)
          { 
              rl.add(new Point2i(leftdown.x-count,i)); count++;
          }
           rs=off-1;
      }
      else if(off==6)//5连获胜
      {
       int count=1; 
          for(int i=leftdown.y+1;i<rightup.y;i++)
          { 
              rl.add(new Point2i(leftdown.x-count,i)); count++;
          }
          rs=5;
      }
      else if(off==5)//?0x00?
      {
           if(Isalive(leftdown)&&Isalive(rightup))
           {
              int count=1; 
          for(int i=leftdown.y+1;i<rightup.y;i++)
          { 
              rl.add(new Point2i(leftdown.x-count,i)); count++;
          }
               rs=4;
           }
      }
      else if(off==4)
      {
          // _00x_
          if(Isalive(leftdown)&&Isalive(rightup)){
              if(leftdown.y-1>=0&&leftdown.x+1<l&&table.get(new Point2i(leftdown.x+1,leftdown.y-1)).intValue()==-1&&Isalive(new Point2i(leftdown.x+2,leftdown.y-2)))
                {
                     rl.add(new Point2i(leftdown.x+1,leftdown.y-1));
                     int count=1; 
                   for(int i=leftdown.y+1;i<rightup.y;i++)
                    { 
                     rl.add(new Point2i(leftdown.x-count,i)); count++;
                    }
                      rs=4;
                }
              else if(rightup.y+1<l&&rightup.x-1>=0&&table.get(new Point2i(rightup.x-1,rightup.y+1)).intValue()==-1&&Isalive(new Point2i(rightup.x-2,rightup.y+2)))
                {
                     int count=1; 
                   for(int i=leftdown.y+1;i<rightup.y;i++)
                    { 
                     rl.add(new Point2i(leftdown.x-count,i)); count++;
                    }
                     rl.add(new Point2i(rightup.x-1,rightup.y+1));
                      rs=4;
                }  
              else {
                   int count=1; 
                   for(int i=leftdown.y+1;i<rightup.y;i++)
                    { 
                     rl.add(new Point2i(leftdown.x-count,i)); count++;
                    }
                    rs=3;
              }
           } 
      }
      else if(off==3){
         
          // _0x_
          if(Isalive(leftdown)&&Isalive(rightup)){
            //_0x_0_   
            if(rightup.y+2<l&&rightup.x-2>=0&&table.get(new Point2i(rightup.x-1,rightup.y+1)).intValue()==-1&&table.get(new Point2i(rightup.x-2,rightup.y+2)).intValue()==0)
            {
                 int count=1; 
                   for(int i=leftdown.y+1;i<rightup.y;i++)
                    { 
                     rl.add(new Point2i(leftdown.x-count,i)); count++;
                    }
                 rl.add(new Point2i(rightup.x-1,rightup.y+1));
                 rs=3;
            }
            //_0x_00  
            else if(rightup.y+2<l&&rightup.x-2>=0&&table.get(new Point2i(rightup.x-1,rightup.y+1)).intValue()==-1&&table.get(new Point2i(rightup.x-2,rightup.y+2)).intValue()==-1&&Isalive(new Point2i(rightup.x-3,rightup.y+3)))
            {
                 int count=1; 
                   for(int i=leftdown.y+1;i<rightup.y;i++)
                    { 
                     rl.add(new Point2i(leftdown.x-count,i)); count++;
                    }
                 rl.add(new Point2i(rightup.x-1,rightup.y+1));
                 rl.add(new Point2i(rightup.x-2,rightup.y+2));
                 rs=4;
            }
            //  _0_0x_ 
            else if(leftdown.y-2>=0&&leftdown.x+2<l&&table.get(new Point2i(leftdown.x+1,leftdown.y-1)).intValue()==-1&&table.get(new Point2i(leftdown.x+2,leftdown.y-2)).intValue()==0)
            {
                rl.add(new Point2i(leftdown.x+1,leftdown.y-1)); 
                int count=1; 
                   for(int i=leftdown.y+1;i<rightup.y;i++)
                    { 
                     rl.add(new Point2i(leftdown.x-count,i)); count++;
                    }
                 rs=3;
            }
             //  00_0x_ 
            else if(leftdown.y-2>=0&&leftdown.x+2<l&&table.get(new Point2i(leftdown.x+1,leftdown.y-1)).intValue()==-1&&table.get(new Point2i(leftdown.x+2,leftdown.y-2)).intValue()==-1&&Isalive(new Point2i(leftdown.x+3,leftdown.y-3)))
            {
                rl.add(new Point2i(leftdown.x+2,leftdown.y-2)); 
                rl.add(new Point2i(leftdown.x+1,leftdown.y-1)); 
                int count=1; 
                   for(int i=leftdown.y+1;i<rightup.y;i++)
                    { 
                     rl.add(new Point2i(leftdown.x-count,i)); count++;
                    }
                 rs=4;
            }
          }
      }
      else if(off==2){
        
          // _x_
          if(Isalive(leftdown)&&Isalive(rightup)){
            //_x_00_   
            if(rightup.y+3<l&&rightup.x-3>=0&&table.get(new Point2i(rightup.x-1,rightup.y+1)).intValue()==-1&&table.get(new Point2i(rightup.x-2,rightup.y+2)).intValue()==-1&&table.get(new Point2i(rightup.x-3,rightup.y+3)).intValue()==0)
            {
                 int count=1; 
                   for(int i=leftdown.y+1;i<rightup.y;i++)
                    { 
                     rl.add(new Point2i(leftdown.x-count,i)); count++;
                    }
                 rl.add(new Point2i(rightup.x-1,rightup.y+1));
                  rl.add(new Point2i(rightup.x-2,rightup.y+2));
                 rs=3;
            }
            //_x_000  
            else if(rightup.y+3<l&&rightup.x-3>=0&&table.get(new Point2i(rightup.x-1,rightup.y+1)).intValue()==-1&&table.get(new Point2i(rightup.x-2,rightup.y+2)).intValue()==-1&&table.get(new Point2i(rightup.x-3,rightup.y+3)).intValue()==-1&&Isalive(new Point2i(rightup.x-4,rightup.y+4)))
            {
                  int count=1; 
                   for(int i=leftdown.y+1;i<rightup.y;i++)
                    { 
                     rl.add(new Point2i(leftdown.x-count,i)); count++;
                    }
                 rl.add(new Point2i(rightup.x-1,rightup.y+1));
                  rl.add(new Point2i(rightup.x-2,rightup.y+2));
                  rl.add(new Point2i(rightup.x-3,rightup.y+3));
                 rs=4;
            }
            //  _00_x_ 
            else if(leftdown.y-3>=0&&leftdown.x+3<l&&table.get(new Point2i(leftdown.x+1,leftdown.y-1)).intValue()==-1&&table.get(new Point2i(leftdown.x+2,leftdown.y-2)).intValue()==-1&&table.get(new Point2i(leftdown.x+3,leftdown.y-3)).intValue()==0)
            {
                rl.add(new Point2i(leftdown.x+2,leftdown.y-2)); 
                 rl.add(new Point2i(leftdown.x+1,leftdown.y-1)); 
                int count=1; 
                   for(int i=leftdown.y+1;i<rightup.y;i++)
                    { 
                     rl.add(new Point2i(leftdown.x-count,i)); count++;
                    }
                 rs=3;
            }
             //  000_x_ 
            else if(leftdown.y-3>=0&&leftdown.x+3<l&&table.get(new Point2i(leftdown.x+1,leftdown.y-1)).intValue()==-1&&table.get(new Point2i(leftdown.x+2,leftdown.y-2)).intValue()==-1&&table.get(new Point2i(leftdown.x+3,leftdown.y-3)).intValue()==-1&&Isalive(new Point2i(leftdown.x+4,leftdown.y-4)))
            {
                  rl.add(new Point2i(leftdown.x+3,leftdown.y-3)); 
                 rl.add(new Point2i(leftdown.x+2,leftdown.y-2)); 
                   rl.add(new Point2i(leftdown.x+1,leftdown.y-1)); 
                
                int count=1; 
                   for(int i=leftdown.y+1;i<rightup.y;i++)
                    { 
                     rl.add(new Point2i(leftdown.x-count,i)); count++;
                    }
                 rs=4;
            }
          } 
      } 
  }
  private void dealls()
  {
     ll.clear();
         ls=0;
      int off=rightdown.y-leftup.y;
      if(off>=7) //长连
      {
          int count=1; 
          for(int i=leftup.y+1;i<rightdown.y;i++)
          { 
              ll.add(new Point2i(leftup.x+count,i)); count++;
          }
           ls=off-1;
      }
      else if(off==6)//5连获胜
      {
       int count=1; 
          for(int i=leftup.y+1;i<rightdown.y;i++)
          { 
              ll.add(new Point2i(leftup.x+count,i)); count++;
          }
          ls=5;
      }
      else if(off==5)//?0x00?
      {
           if(Isalive(leftup)&&Isalive(rightdown))
           {
              int count=1; 
           for(int i=leftup.y+1;i<rightdown.y;i++)
          { 
              ll.add(new Point2i(leftup.x+count,i)); count++;
          }
               ls=4;
           }
      }
      else if(off==4)
      {
         
          // _00x_
          if(Isalive(leftup)&&Isalive(rightdown)){
              if(leftup.y-1>=0&&leftup.x-1>=0&&table.get(new Point2i(leftup.x-1,leftup.y-1)).intValue()==-1&&Isalive(new Point2i(leftup.x-2,leftup.y-2)))
                {
                     ll.add(new Point2i(leftup.x-1,leftup.y-1));
                     int count=1; 
                   for(int i=leftup.y+1;i<rightdown.y;i++)
                    { 
                      ll.add(new Point2i(leftup.x+count,i)); count++;
                    }
                      ls=4;
                }
              else if(rightdown.y+1<l&&rightdown.x+1<l&&table.get(new Point2i(rightdown.x+1,rightdown.y+1)).intValue()==-1&&Isalive(new Point2i(rightdown.x+2,rightdown.y+2)))
                {
                     int count=1; 
                   for(int i=leftup.y+1;i<rightdown.y;i++)
                    { 
                      ll.add(new Point2i(leftup.x+count,i)); count++;
                    }
                     ll.add(new Point2i(rightdown.x+1,rightdown.y+1));
                      ls=4;
                }  
              else {
                   int count=1; 
                   for(int i=leftup.y+1;i<rightdown.y;i++)
                    { 
                      ll.add(new Point2i(leftup.x+count,i)); count++;
                    }
                    ls=3;
              }
           } 
      }
      else if(off==3){
        
          // _0x_
          if(Isalive(leftup)&&Isalive(rightdown)){
            //_0x_0_   
            if(rightdown.y+2<l&&rightdown.x+2<l&&table.get(new Point2i(rightdown.x+1,rightdown.y+1)).intValue()==-1&&table.get(new Point2i(rightdown.x+2,rightdown.y+2)).intValue()==0)
            {
                 int count=1; 
                    for(int i=leftup.y+1;i<rightdown.y;i++)
                    { 
                      ll.add(new Point2i(leftup.x+count,i)); count++;
                    }
                 ll.add(new Point2i(rightdown.x+1,rightdown.y+1));
                 ls=3;
            }
            //_0x_00  
            else if(rightdown.y+2<l&&rightdown.x+2<l&&table.get(new Point2i(rightdown.x+1,rightdown.y+1)).intValue()==-1&&table.get(new Point2i(rightdown.x+2,rightdown.y+2)).intValue()==-1&&Isalive(new Point2i(rightdown.x+3,rightdown.y+3)))
            {
                 int count=1; 
                    for(int i=leftup.y+1;i<rightdown.y;i++)
                    { 
                      ll.add(new Point2i(leftup.x+count,i)); count++;
                    }
                 ll.add(new Point2i(rightdown.x+1,rightdown.y+1));
                  ll.add(new Point2i(rightdown.x+2,rightdown.y+2));
                 ls=4;
            }
            //  _0_0x_ 
            else if(leftup.y-2>=0&&leftup.x-2>=0&&table.get(new Point2i(leftup.x-1,leftup.y-1)).intValue()==-1&&table.get(new Point2i(leftup.x-2,leftup.y-2)).intValue()==0)
            {
                ll.add(new Point2i(leftup.x-1,leftup.y-1)); 
                int count=1; 
                   for(int i=leftup.y+1;i<rightdown.y;i++)
                    { 
                      ll.add(new Point2i(leftup.x+count,i)); count++;
                    }
                 ls=3;
            }
             //  00_0x_ 
            else if(leftup.y-2>=0&&leftup.x-2>=0&&table.get(new Point2i(leftup.x-1,leftup.y-1)).intValue()==-1&&table.get(new Point2i(leftup.x-2,leftup.y-2)).intValue()==-1&&Isalive(new Point2i(leftup.x-3,leftup.y-3)))
            {
               ll.add(new Point2i(leftup.x-2,leftup.y-2)); 
               ll.add(new Point2i(leftup.x-1,leftup.y-1)); 
                 int count=1; 
                   for(int i=leftup.y+1;i<rightdown.y;i++)
                    { 
                      ll.add(new Point2i(leftup.x+count,i)); count++;
                    }
                 ls=4;
            }
          }
      }
      else if(off==2){
        
          // _x_
          if(Isalive(leftup)&&Isalive(rightdown)){
            //_x_00_   
            if(rightdown.y+3<l&&rightdown.x+3<l&&table.get(new Point2i(rightdown.x+1,rightdown.y+1)).intValue()==-1&&table.get(new Point2i(rightdown.x+2,rightdown.y+2)).intValue()==-1&&table.get(new Point2i(rightdown.x+3,rightdown.y+3)).intValue()==0)
            {
                 int count=1; 
                    for(int i=leftup.y+1;i<rightdown.y;i++)
                    { 
                      ll.add(new Point2i(leftup.x+count,i)); count++;
                    }
                 ll.add(new Point2i(rightdown.x+1,rightdown.y+1));
                  ll.add(new Point2i(rightdown.x+2,rightdown.y+2));
                 ls=3;
            }
            //_x_000  
            else if(rightdown.y+3<l&&rightdown.x+3<l&&table.get(new Point2i(rightdown.x+1,rightdown.y+1)).intValue()==-1&&table.get(new Point2i(rightdown.x+2,rightdown.y+2)).intValue()==-1&&table.get(new Point2i(rightdown.x+3,rightdown.y+3)).intValue()==-1&&Isalive(new Point2i(rightdown.x+4,rightdown.y+4)))
            {
                  int count=1; 
                   for(int i=leftup.y+1;i<rightdown.y;i++)
                    { 
                      ll.add(new Point2i(leftup.x+count,i)); count++;
                    }
                 ll.add(new Point2i(rightdown.x+1,rightdown.y+1));
                  ll.add(new Point2i(rightdown.x+2,rightdown.y+2));
                  ll.add(new Point2i(rightdown.x+3,rightdown.y+3));
                  
                 ls=4;
            }
            //  _00_x_ 
            else if(leftup.y-3>=0&&leftup.x-3>=0&&table.get(new Point2i(leftup.x-1,leftup.y-1)).intValue()==-1&&table.get(new Point2i(leftup.x-2,leftup.y-2)).intValue()==-1&&table.get(new Point2i(leftup.x-3,leftup.y-3)).intValue()==0)
            {
                ll.add(new Point2i(leftup.x-2,leftup.y-2)); 
                 ll.add(new Point2i(leftup.x-1,leftup.y-1)); 
                int count=1; 
                    for(int i=leftup.y+1;i<rightdown.y;i++)
                    { 
                      ll.add(new Point2i(leftup.x+count,i)); count++;
                    }
                 ls=3;
            }
             //  000_x_ 
            else if(leftup.y-3>=0&&leftup.x-3>=0&&table.get(new Point2i(leftup.x-1,leftup.y-1)).intValue()==-1&&table.get(new Point2i(leftup.x-2,leftup.y-2)).intValue()==-1&&table.get(new Point2i(leftup.x-3,leftup.y-3)).intValue()==-1&&Isalive(new Point2i(leftup.x-4,leftup.y-4)))
            {
                 ll.add(new Point2i(leftup.x-3,leftup.y-3)); 
                ll.add(new Point2i(leftup.x-2,leftup.y-2)); 
                 ll.add(new Point2i(leftup.x-1,leftup.y-1)); 
                
                int count=1; 
                   for(int i=leftup.y+1;i<rightdown.y;i++)
                    { 
                      ll.add(new Point2i(leftup.x+count,i)); count++;
                    }
                 ls=4;
            }
          } 
      } 
  }
  
  /*
   *  Method to check whether a black chess has break the gaming rule.
   *  Please make sure the Constructor has been initialized correctly
      so as to update the chess table.
   */
  public boolean Isforbid(){
      
       if(table.get(new Point2i(last.x,last.y)).intValue()==1)
           return false;
       else 
       {
             side();
             dealver();
             dealhor();
             dealrs();
             dealls();
           int forbid_index=ver+hor+rs+ls;
          if(ver==5||hor==5||rs==5||ls==5||forbid_index<=5||(forbid_index==7&&(ver==3||hor==3||rs==3||ls==3)))
              return false;
          else return true;
       }
  }
  private boolean Isalive(Point2i p)
  {
     if(((p.x>=0&&p.x<l)&&(p.y>=0&&p.y<l))&&(table.get(p).intValue()==0)) return true;
     return false;
  }
   
}
